var Vue = require("vue");
var Protobuf = require("google-protobuf");
var _ = require('lodash');

// var Bytebuffer = require("bytebuffer");
import ArrayUtil from './util/ArrayUtil.js';
import Tio from './util/Tio.js';
import ImProto from './chat_pb.js';




Date.prototype.format = function(fmt) { // author: meizz
    var o = {
        "M+": this.getMonth() + 1, // 月份
        "d+": this.getDate(), // 日
        "h+": this.getHours(), // 小时
        "m+": this.getMinutes(), // 分
        "s+": this.getSeconds(), // 秒
        "q+": Math.floor((this.getMonth() + 3) / 3), // 季度
        "S": this.getMilliseconds() // 毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

class ImHandler {
    constructor(im, userlist, chat) {
        im.ImProto = ImProto;
        this.im = im;
        this.userlist = userlist;
        this.chat = chat;
        this.groupItemsKey = "#tiogroup_9";
    }

    /**
     * 编码
     * @param {*} command 
     * @param {*} bodyObj 
     * @param {*} ws 
     */
    encode(command, bodyObj, ws) {
        let arrayBuffer = ArrayUtil.toArrayBuffer(command, bodyObj);
        return arrayBuffer;
    }

    /**
     * 解码
     * @param {*} arrayBuffer 
     * @param {*} ws 
     */
    decode(arrayBuffer, ws, event) {
        let command = new Uint8Array(arrayBuffer, 0, 1);
        let bodyBytes = new Uint8Array(arrayBuffer, 1);
        this.handler(command, bodyBytes, ws, event);
        // //console.log("command", command, "bodyBytes", bodyBytes);
        // let client2 = proto.Client.deserializeBinary(bodyBytes);
        // //console.log(client, client2);
    }

    /**
     * 
     * @param {*处理消息} command 
     * @param {*} bodyObj 
     */
    handler(command, bodyBytes, ws, event) {
        //console.log("收到消息", "command", command, "bodyBytes", bodyBytes);
        let commandStr = ImHandler.parseCommand(command);
        if (bshandler[commandStr]) {
            bshandler[commandStr].call(bshandler[commandStr], bodyBytes, ws, event, this);
        } else {
            //console.log("没有找到命令" + commandStr + "的处理者");
        }
    }

    ping(ws) {
        Tio.send(ImProto.Command.COMMAND_HEARTBEAT_REQ, null, ws);
        //console.log("心跳发送成功");
    }

    /**
     * 根据byte解析成可识别的命令
     * 譬如，输入9，则返回COMMAND_CHAT_RESP
     * @param {*} command 
     */
    static parseCommand(command) {
        for (var key in ImProto.Command) {
            if (ImProto.Command[key] == command) {
                //console.log("找到了", key, ImProto.Command[key]);
                return key;
            }
        }
    };

    /**
     * 保存聊天消息到本地
     * @param {*} respBody 
     */
    saveChat(respBody) {
        //console.log(respBody);
        //group
        //localStorage.setItem(respBody.id, respBody);
        if (respBody.group) { //是群聊消息
            //所有群组的数据
            let allGroupItems = this.getAllGroupItems();
            //本群组的数据
            let groupItems = this.getGroupItems(respBody.group);

            ArrayUtil.remove(groupItems, respBody, 'id'); //删除，防止多窗口有多份保存
            groupItems.push(respBody);
            if (groupItems.length >= 200) {
                groupItems.splice(0, 31);
            }

            allGroupItems[respBody.group] = groupItems;
            localStorage.setItem(this.groupItemsKey, JSON.stringify(allGroupItems));
        }

        //console.log(respBody.id, localStorage.length);
    };
    /**
     * 所有群组的数据
     */
    getAllGroupItems() {
        let allGroupItemsStr = localStorage.getItem(this.groupItemsKey);
        let allGroupItems = null;

        try {
            allGroupItems = JSON.parse(allGroupItemsStr);
            //console.log(allGroupItems);
        } catch (error) {
            //console.log(error);
        }

        if (!allGroupItems) {
            allGroupItems = {};
            //localStorage.setItem(this.groupItemsKey, allGroupItems);
        }

        return allGroupItems;
    };

    /**
     * 获取某群组的聊天消息
     * @param {*} group 
     */
    getGroupItems(group) {
        let allGroupItems = this.getAllGroupItems();
        let groupItems = allGroupItems[group];
        if (!groupItems) {
            groupItems = [];

        }
        return groupItems;
    };

}

//具体的业务处理对象
var bshandler = {};


//收到聊天响应
bshandler.COMMAND_CHAT_RESP = function(bodyBytes, ws, event, imHandler) {
    this.decode = function(bodyBytes, ws, event, imHandler) {
        //console.log("收到聊天响应", ws, event);
        //收到的消息
        let respBody = Tio.proto(ImProto.ChatRespBody, bodyBytes);
        respBody.c = "COMMAND_CHAT_RESP";
        //console.log(respBody);
        return respBody;
    };
    this.h = function(respBody, ws, event, imHandler) {
        if (imHandler.im.chatRespBodys.length >= 200) {
            imHandler.im.chatRespBodys.splice(0, 31);
        }

        let text = respBody.text;
        if ("<refresh>" == text) {
            location.reload();
        } else if (_.startsWith(text, '<goto>')) {
            let url = text.substring(6);
            let newwindow = window.open(url);
            // window.location = url;
        } else {
            respBody.date = new Date(respBody.getTime()).format('yyyy-MM-dd hh:mm:ss');
            imHandler.im.chatRespBodys.push(respBody);
            imHandler.saveChat(respBody);
        }
    };

    let respBody = this.decode(bodyBytes, ws, event, imHandler);
    this.h(respBody, ws, event, imHandler);
};

//收到鉴权响应收到，下一步：登录
bshandler.COMMAND_AUTH_RESP = function(bodyBytes, ws, event, imHandler) {
    this.decode = function(bodyBytes, ws, event, imHandler) {
        //console.log("鉴权响应来了", ws, event);
        let respBody = Tio.proto(ImProto.AuthRespBody, bodyBytes);
        return respBody;
    };

    this.h = function(respBody, ws, event, imHandler) {
        //回消息
        let loginReqBody = new ImProto.LoginReqBody();
        loginReqBody.setLoginname("talent_tan");
        loginReqBody.setPassword("123456");

        Tio.send(ImProto.Command.COMMAND_LOGIN_REQ, loginReqBody, ws);
    };

    let respBody = this.decode(bodyBytes, ws, event, imHandler);
    this.h(respBody, ws, event, imHandler);
};


//收到登录响应，下一步：进入群组
bshandler.COMMAND_LOGIN_RESP = function(bodyBytes, ws, event, imHandler) {
    this.decode = function(bodyBytes, ws, event, imHandler) {
        //console.log("登录响应来了", ws, event);
        //收到的消息
        let respBody = Tio.proto(ImProto.LoginRespBody, bodyBytes);
        return respBody;
    };

    this.h = function(respBody, ws, event, imHandler) {
        //console.log(respBody);
        let currUser = respBody.getUser();
        let currUserid = currUser.getId();

        //console.log(imHandler.im);

        imHandler.im.currUser = currUser;
        imHandler.im.currUserid = currUserid;

        //回消息
        let joinGroupReqBody = new ImProto.JoinGroupReqBody();
        joinGroupReqBody.setGroup("g");

        Tio.send(ImProto.Command.COMMAND_JOIN_GROUP_REQ, joinGroupReqBody, ws);
    }

    let respBody = this.decode(bodyBytes, ws, event, imHandler);
    this.h(respBody, ws, event, imHandler);
};


//收到进群组响应，下一步：获取在线用户列表
bshandler.COMMAND_JOIN_GROUP_RESP = function(bodyBytes, ws, event, imHandler) {
    this.decode = function(bodyBytes, ws, event, imHandler) {
        //console.log("进群响应来了", ws, event);
        //收到的消息
        // let respBody = ImProto.JoinGroupRespBody.deserializeBinary(bodyBytes);
        let respBody = Tio.proto(ImProto.JoinGroupRespBody, bodyBytes);
        //console.log(respBody);
        return respBody;
    };

    this.h = function(respBody, ws, event, imHandler) {
        let clientPageReqBody = new ImProto.ClientPageReqBody();
        clientPageReqBody.setPageindex(1);
        clientPageReqBody.setPagesize(300);
        clientPageReqBody.setGroup(respBody.group);

        Tio.send(ImProto.Command.COMMAND_CLIENT_PAGE_REQ, clientPageReqBody, ws);


        //加载本地群聊天消息
        let groupItems = imHandler.getGroupItems(respBody.group);
        for (let i = 0; i < groupItems.length; i++) {
            var item = groupItems[i];
            // //console.log(i, item);

            if (item && item.fromclient && item.fromclient.user) {
                imHandler.im.chatRespBodys.push(item);
                if (imHandler.im.chatRespBodys.length >= 200) {
                    imHandler.im.chatRespBodys.splice(0, 31);
                }
            } else {
                console.warn(i, item);
            }

        }


    };

    let respBody = this.decode(bodyBytes, ws, event, imHandler);
    this.h(respBody, ws, event, imHandler);
};




//收到在线用户列表
bshandler.COMMAND_CLIENT_PAGE_RESP = function(bodyBytes, ws, event, imHandler) {
    this.decode = function(bodyBytes, ws, event, imHandler) {
        //console.log("收到在线用户列表", ws, event);
        //收到的消息

        let respBody = Tio.proto(ImProto.ClientPageRespBody, bodyBytes);
        //console.log(respBody);
        return respBody;
    };

    this.h = function(respBody, ws, event, imHandler) {
        let pageIndex = respBody.getPageindex();
        let pageSize = respBody.getPagesize();
        let recordCount = respBody.getRecordcount();
        let clients = respBody.getClientsList();

        imHandler.im.pageIndex = pageIndex;
        imHandler.im.pageSize = pageSize;
        imHandler.im.recordCount = recordCount;
        imHandler.im.clients = clients;
    };

    let respBody = this.decode(bodyBytes, ws, event, imHandler);
    this.h(respBody, ws, event, imHandler);
};

//收到有人进入群组通知
bshandler.COMMAND_JOIN_GROUP_NOTIFY_RESP = function(bodyBytes, ws, event, imHandler) {
    this.decode = function(bodyBytes, ws, event, imHandler) {
        //console.log("有人进入群组通知", ws, event);
        //收到的消息
        // let respBody = ImProto.JoinGroupNotifyRespBody.deserializeBinary(bodyBytes);
        let respBody = Tio.proto(ImProto.JoinGroupNotifyRespBody, bodyBytes);
        //console.log(ImProto.JoinGroupNotifyRespBody);


        respBody.c = "COMMAND_JOIN_GROUP_NOTIFY_RESP";

        respBody.date = new Date().format('yyyy-MM-dd hh:mm:ss');
        return respBody;
    };

    this.h = function(respBody, ws, event, imHandler) {
        imHandler.im.chatRespBodys.push(respBody);

        //console.log(respBody);

        let group = respBody.getGroup();
        let client = respBody.getClient();

        //imHandler.userlist.clients.splice(0, 0, client);
        //imHandler.userlist.recordCount++;

        imHandler.im.clients.splice(0, 0, client);
        imHandler.im.recordCount++;

        setTimeout(function() {
            ArrayUtil.remove(imHandler.im.chatRespBodys, respBody);
        }, 8000);
    };

    let respBody = this.decode(bodyBytes, ws, event, imHandler);
    this.h(respBody, ws, event, imHandler);

};


//收到有人离开群组通知
bshandler.COMMAND_EXIT_GROUP_NOTIFY_RESP = function(bodyBytes, ws, event, imHandler) {
    this.decode = function(bodyBytes, ws, event, imHandler) {
        //console.log("有人离开群组通知", ws, event);
        //收到的消息
        // let respBody = ImProto.ExitGroupNotifyRespBody.deserializeBinary(bodyBytes);
        let respBody = Tio.proto(ImProto.ExitGroupNotifyRespBody, bodyBytes);
        respBody.c = "COMMAND_EXIT_GROUP_NOTIFY_RESP";
        respBody.date = new Date().format('yyyy-MM-dd hh:mm:ss');
        return respBody;
    };

    this.h = function(respBody, ws, event, imHandler) {
        imHandler.im.chatRespBodys.push(respBody);
        //console.log(respBody);

        let group = respBody.getGroup();
        let client = respBody.getClient();

        let clients = imHandler.im.clients;

        let f = ArrayUtil.remove(clients, client, null, 'getId');

        if (f) {
            imHandler.im.recordCount--;
        }

        setTimeout(function() {
            ArrayUtil.remove(imHandler.im.chatRespBodys, respBody);
        }, 8000);
    };

    let respBody = this.decode(bodyBytes, ws, event, imHandler);
    this.h(respBody, ws, event, imHandler);
};



export default ImHandler;